package com.cangxuan.backend.utils;

import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

/**
 * 安全工具类
 */
@Slf4j
public class SecurityUtils {

    public static Base64.Encoder encoder;
    public static Base64.Decoder decoder;

    static {
        encoder = Base64.getEncoder();
        decoder = Base64.getDecoder();
    }

    public static String md5(String source) {
        //创建一个消息摘要对象
        MessageDigest digest;
        try {
            digest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        //添加要获取摘要的数据
        digest.update(source.getBytes(StandardCharsets.UTF_8));
        //获取摘要
        byte[] results = digest.digest();
        return new BigInteger(1, results).toString(16);
    }


    /**
     * AES(ECB)解密，过程：解码->解密
     * @param key
     * @param ciphertext 密文
     * @return 明文
     */
    public static String decryptAES(String key, String ciphertext) {
        String result = null;
        //创建一个密钥对象，第1个参数是key的字节数组，第2参数是算法
        SecretKey secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
        try {
            //创建一个加密算法对象，参数为填充模式
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            //初始化加密算法对象，第1个参数是算法动作（是加密或者解密），第2个参数就是密钥对象
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            //执行加密算法，参数是密文的字节数组
            byte[] data = cipher.doFinal(Base64.getDecoder().decode(ciphertext));
            //将字节数组转换为字符串
            result = new String(data, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            return result;
        }
    }

    /**
     * RSA解密
     *
     * @param priKey     私钥
     * @param ciphertext 密文
     * @return 明文
     */
    public static String decryptRSA(String priKey, String ciphertext) {
        String result = null;
        try {
            //创建一个密钥工厂对象
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            //创建一个密钥规格对象
            KeySpec keySpec = new PKCS8EncodedKeySpec(decoder.decode(priKey));
            //创建私钥对象
            PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
            //从这里开始，使用私钥进行解密
            //创建一个加密算法对象，参数为填充模式
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            //初始化加密算法对象，第1个参数是算法动作（是加密或者解密），第2个参数就是密钥对象
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            //执行加密算法，参数是密文的字节数组
            byte[] data = cipher.doFinal(decoder.decode(ciphertext));
            //将字节数组转换为字符串
            result = new String(data, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            return result;
        }
    }
}
